/*
 * Message.cpp
 *
 *  Created on: 6 mei 2013
 *      Author: Wietse
 */

#include "Message.h"
#include "Swarm.h"

#include <Math.h>
#include <iostream>

/**
 * Default constructor
 */
Message::Message()
{
	this->position = Position(0.0, 0.0);
	this->frame = 0;
	this->sourceType = UNKNOWN;
	this->senderID = 0;
	this->data = Data();
}

/**
 * Preferred constructor
 */
Message::Message(Component source, int sender, Position& start, Data& data)
{
	this->position = start;
	this->frame = 0;
	this->sourceType = source;
	this->senderID = sender;//sender;
	this->data = data;
}

/**
 * Destructor
 */
Message::~Message()
{
	// Destroy the start position of this message
	position.~Position();

	//Destroy the data object attached to this message
	data.~Data();
}

Position Message::getStart()
{
	return position;
}

Component Message::getSourceType()
{
	return sourceType;
}

int	Message::getSenderID()
{
	return senderID;
}

Data Message::getData()
{
	return data;
}

/**
 * Check if the given position is in range of the message
 */
bool Message::inRange(Position *other)
{
	// Calculate the Euclidian distance
	double dis = position.distance(other);

	// Check if the distance is smaller than the radius of the message
	if(dis < MESSAGE_PROPAGATION)
	{
		return true;
	}
	return false;
}

/**
 * Update the radius of the Message
 */
void Message::update(Swarm *swarm)
{
	// Increment the number of frames
	frame++;

	// Check if radius has exceeded the maximum propagation distance
	if(frame >= 2 && swarm != NULL)
	{
		// Remove message from vector in swarm and destroy the message
		swarm->removeMessage(this);
	}
}

/**
 * Print information about this message to the console
 */
void Message::printMessage()
{
	std::cout << "Message: ";
	printSourceType();
	std::cout << senderID 		<< std::endl;
	std::cout << "frame: " << frame << std::endl;
	std::cout << "Position: " 	<< position.toString()	<< std::endl;
	std::cout << "Data:";
	data.printData();
	std::cout << std::endl;
}

/**
 * Print sourceType to console
 */
void Message::printSourceType()
{
	switch(sourceType)
	{
	case 	UNKNOWN:
		std::cout << "Unknown ";
		break;
	case	BASESTATION:
		std::cout << "Basestation ";
		break;
	case	QUADCOPTER:
		std::cout << "Quadcopter ";
		break;
	case	CRAWLER:
		std::cout << "Crawler ";
		break;
	}
}
